package sharewithus.analyzer.utils;

import java.io.Serializable;
import java.util.Iterator;
import java.util.NoSuchElementException;


/**
 * 自定义单向链表
 * 
 * @author terry
 * 
 * @param <T>
 */
public class DeLinkedList<T> implements Iterable<T>{

	/**
	 * 
	 */
	private static final long serialVersionUID = -9068551311817174423L;

	@SuppressWarnings("serial")
	private static class Entry<T> implements Serializable{
		T item;
		Entry<T> next;

		public Entry(T item, Entry<T> next) {
			this.item = item;
			this.next = next;
		}
		
		public String toString(){
			return item.toString();
		}
	}

	private Entry<T> head, tail;

	/**
	 * 向头部添加元素
	 * 
	 * @param t
	 */
	public void addFirst(T t) {
		Entry<T> newEntry = new Entry<T>(t, head);
		if (isEmpty())// 如果链表为空,则尾指针指向新元素
			tail = newEntry;
		head = newEntry;// 无论链表是否为空,头指针都指向新元素
	}

	/**
	 * 向尾部添加元素
	 * @param t
	 */
	public void addLast(T t) {
		Entry<T> newEntry = new Entry<T>(t, null);
		if (isEmpty())//如果链表为空,则头指针指向新元素
			head = newEntry;
		else
			tail.next = newEntry;//如果链表非空,则将旧的尾指针的next指向新元素
		tail = newEntry;//将尾指针指向新元素
	}
	
	public void add(T t){
		addLast(t);
	}
	
	public T removeFirst() {
		if(isEmpty()) return null;
		T t = head.item;
		if (head.next == null) //如果只有1个元素,则尾指针为null
			tail = null;
		head = head.next;//头指针指向下一个元素
		return t;
	}
	
	
	public boolean isEmpty() {
		return head == null;
	}

	public Iterator<T> iterator() {
		return new LinkIterator(head);
	}
	
	private class LinkIterator implements Iterator<T> {
		Entry<T> itr;

		public LinkIterator(Entry<T> begin) {
			itr = begin;
		}

		public boolean hasNext() {
			return itr != null;
		}

		public T next() {
			if (itr == null) {
				throw new NoSuchElementException();
			}
			Entry<T> cur = itr;
			itr = itr.next;
			return cur.item;
		}

		public void remove() {
			DeLinkedList.this.removeFirst();
		}
	}
	
	public String toString() {
		StringBuilder buf = new StringBuilder();
		Entry<T> pCur = head;

		while (pCur != null) {
			buf.append(pCur.item.toString());
			buf.append(' ');
			pCur = pCur.next;
		}

		return buf.toString();
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DeLinkedList<String> dlist = new DeLinkedList<String>();
		dlist.addLast("a");dlist.addLast("b");dlist.addLast("c");
		System.out.println(dlist);
		for (String string : dlist) {
			System.out.println(string);
		}
	}
}
